package hxy.bytecode.algorithm.rsa;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
 
public class RSACrypt {
 
  
 
    /**
     * 公钥加密
     *
     * @param publicKey     公钥
     * @param plainTextData 明文数据
     * @return
     * @throws Exception 加密过程中的异常信息
     */
    public static String encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception {
        if (publicKey == null) {
            throw new Exception("加密公钥为空, 请设置");
        }
        Cipher cipher = null;
        try {
            // 使用默认RSA
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] output = cipher.doFinal(plainTextData);
            return bytesToHexString(output);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此加密算法");
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("加密公钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("明文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("明文数据已损坏");
        }
    }
 
 
 
   /**
    * 生成16进制字符串这个要看具体后端处理方式选择返回什么字符串有的只需要Basic64就行了
    * @param bArr
    * @return
    */
   public static  String bytesToHexString(byte[] bArr) {
        StringBuffer sb = new StringBuffer(bArr.length);
        String sTmp;
 
        for (int i = 0; i < bArr.length; i++) {
            sTmp = Integer.toHexString(0xFF & bArr[i]);
            if (sTmp.length() < 2)
                sb.append(0);
            sb.append(sTmp.toUpperCase());
        }
 
        return sb.toString();
    }
   
 
   
/**
 * 根据modulus 和publicExponent还原 公钥    
 * @param modulus
 * @param publicExponent
 * @return
 * @throws NoSuchAlgorithmException
 * @throws InvalidKeySpecException
 */
  public static RSAPublicKey getPublicKey(String   modulus,String  publicExponent)
          throws NoSuchAlgorithmException, InvalidKeySpecException {
	
	  BigInteger bigIntModulus = new BigInteger(modulus,16);
 
        BigInteger bigIntPrivateExponent = new BigInteger(publicExponent,16);
 
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);
 
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
 
        return (RSAPublicKey) publicKey;
 
    }
  
 
 
}